1 00:00:00,610 --> 00:00:01,180 Hey there. 2 00:00:01,180 --> 00:00:05,830 In this lecture, we're going to continue to learn about how to listen to user input by checking out 3 00:00:05,830 --> 00:00:08,200 the Context Action Service. 4 00:00:08,200 --> 00:00:13,240 This service allows us to bind a function to listen to a particular user input. 5 00:00:13,240 --> 00:00:18,040 For example, when some condition is met, like if they have some tool equipped or during a set time 6 00:00:18,040 --> 00:00:24,070 frame, and once we no longer need to listen to that user input, we can unbind the function to no longer 7 00:00:24,070 --> 00:00:24,820 execute. 8 00:00:24,820 --> 00:00:30,430 This service is incredibly useful for creating games that need to have cross-platform support, and 9 00:00:30,430 --> 00:00:36,100 this is because the Context Action service enables us to listen to multiple different inputs simultaneously, 10 00:00:36,100 --> 00:00:38,980 such as mouse inputs and touch inputs. 11 00:00:38,980 --> 00:00:45,100 A context is a condition where a player can perform an action, such as having a tool equipped, and 12 00:00:45,100 --> 00:00:49,960 the action is that input that is performed by the player in that particular context. 13 00:00:50,380 --> 00:00:56,050 In fact, Roblox developers actually recommend using the context action service over the user input 14 00:00:56,050 --> 00:00:57,970 service in most situations. 15 00:00:57,970 --> 00:01:04,060 This is because using the user input service means we have to explicitly check whether or not our player 16 00:01:04,060 --> 00:01:09,880 is in a particular context when an action or an input is being performed, and that's a lot more work 17 00:01:09,880 --> 00:01:11,200 than just binding actions. 18 00:01:11,200 --> 00:01:11,950 Contextually. 19 00:01:11,950 --> 00:01:18,010 Using the Context Action service here in the Roblox documentation, we can read that the Context Action 20 00:01:18,010 --> 00:01:24,610 Service allows an experience to bind user input to contextual actions or actions that are only enabled 21 00:01:24,610 --> 00:01:26,830 under some condition or period of time. 22 00:01:26,830 --> 00:01:31,360 For example, allowing a player to open a door only while close by. 23 00:01:31,360 --> 00:01:37,570 And here it explains to us exactly what is a context, what is an action, and maybe some justification 24 00:01:37,570 --> 00:01:42,220 or reasons for why we should bind actions contextually and inside of the service. 25 00:01:42,220 --> 00:01:46,930 We have some methods such as a binding an action to a particular input. 26 00:01:46,930 --> 00:01:51,670 So for example, here in this example code it shows us binding an action. 27 00:01:51,670 --> 00:01:53,650 They called it honk horn. 28 00:01:53,650 --> 00:02:00,850 It passes a function that's going to handle when input occurs which is handled right here in this function. 29 00:02:00,850 --> 00:02:05,890 And then also passes a boolean which tells us whether or not we would like to display a button on the 30 00:02:05,890 --> 00:02:07,480 screen for mobile players. 31 00:02:07,480 --> 00:02:14,050 And then we also pass the different inputs that are responsible for this particular context. 32 00:02:14,260 --> 00:02:21,070 So if we actually take a look at the bind action function, the parameters is we need a name for this 33 00:02:21,070 --> 00:02:21,670 action. 34 00:02:21,670 --> 00:02:25,870 We need a function that's going to be listening to any input. 35 00:02:26,140 --> 00:02:30,730 We have a boolean that tells us whether or not we would like to create a touch button on the screen, 36 00:02:30,730 --> 00:02:36,340 and then we also pass a list of the different input types that we can listen to for this particular 37 00:02:36,340 --> 00:02:37,060 action. 38 00:02:37,530 --> 00:02:43,500 So back in studio we're going to get the context action service by using the Get Service function. 39 00:02:43,500 --> 00:02:45,780 And we can get Context Action service. 40 00:02:46,410 --> 00:02:51,960 And inside of here if we refer to our context action service, as you can see we have access to the 41 00:02:51,960 --> 00:02:58,260 bind action function which takes the name of the action, the function whether or not we would like 42 00:02:58,260 --> 00:03:04,830 to create a touch button, and then a tuple or a list of the different kinds of inputs that are going 43 00:03:04,830 --> 00:03:07,560 to be listening for this particular action. 44 00:03:08,040 --> 00:03:13,560 So what I'm going to do actually real quick is I'm going to create a function called on action. 45 00:03:14,650 --> 00:03:20,020 And then this is the function that we're going to be passing to our bind action function. 46 00:03:20,020 --> 00:03:26,290 So for example here I'm just going to call this action example action one. 47 00:03:26,560 --> 00:03:30,040 And then we can go ahead and pass a reference to our function. 48 00:03:30,040 --> 00:03:32,470 So this is going to be on action. 49 00:03:32,830 --> 00:03:38,620 And right here it tells us the different arguments that are going to be passed to our function. 50 00:03:38,620 --> 00:03:42,580 In this case it's going to pass the string or the name of the action. 51 00:03:42,580 --> 00:03:45,490 It's going to pass a user input state enum. 52 00:03:45,490 --> 00:03:48,250 And it's going to be passing an input object. 53 00:03:48,250 --> 00:03:52,810 So inside of my function, what I can define here is the name of the action. 54 00:03:53,350 --> 00:03:57,580 The input state as well as the input object. 55 00:03:57,580 --> 00:04:00,970 And here I can denote these as a string. 56 00:04:01,300 --> 00:04:05,830 I can denote this as an enum dot user input state. 57 00:04:05,830 --> 00:04:12,940 And then I can denote this as an input object, after which we can also define whether or not we would 58 00:04:12,940 --> 00:04:16,870 like to create a GUI button on the screen for mobile players. 59 00:04:16,870 --> 00:04:18,790 For this one, I'm just going to say true. 60 00:04:19,630 --> 00:04:25,180 And then after this, we can pass any type of input that we would like this action to listen to. 61 00:04:25,180 --> 00:04:28,750 So for example I can pass like an enum dot Keycode. 62 00:04:28,750 --> 00:04:33,010 Maybe I want to listen to the p uh button on your keyboard. 63 00:04:33,010 --> 00:04:37,780 So we'll pass P, or maybe I want to listen to a touch on the screen. 64 00:04:37,780 --> 00:04:43,120 So I could do enum dot user input type dot touch, or I can even pass. 65 00:04:43,120 --> 00:04:45,370 Maybe I want to listen to mouse input. 66 00:04:45,370 --> 00:04:50,140 So I could do enum dot user input type dot mouse button one. 67 00:04:50,140 --> 00:04:51,130 Let's just do that. 68 00:04:51,550 --> 00:04:57,370 So now this function is going to be handling or listening to these three different inputs. 69 00:04:57,370 --> 00:05:02,560 And it's going to give us some information such as the state of the input, whether or not the input 70 00:05:02,560 --> 00:05:09,100 has began or it ended, as well as some other additional information stored inside of our input object. 71 00:05:09,100 --> 00:05:11,770 And I can bind multiple different actions. 72 00:05:11,770 --> 00:05:15,730 So I'm going to copy this and paste this one here. 73 00:05:15,730 --> 00:05:19,330 And I'm just going to call this one example action two. 74 00:05:19,330 --> 00:05:22,540 And they're both going to be using the exact same function. 75 00:05:22,630 --> 00:05:30,190 And inside of this function all I'm going to do is I'm going to check if the input state is equal to 76 00:05:30,190 --> 00:05:30,850 the enum. 77 00:05:30,850 --> 00:05:34,510 Let's say the user input state of begin right. 78 00:05:34,510 --> 00:05:36,310 So our input began. 79 00:05:36,310 --> 00:05:40,150 We can print something like input began. 80 00:05:40,450 --> 00:05:43,450 And then I'm just going to pass the action name here. 81 00:05:43,450 --> 00:05:48,520 So this will tell us whether or not this is an example action one or example action two. 82 00:05:48,640 --> 00:05:54,040 And then I can create an else if statement and check to see if the input state is equal to the enum 83 00:05:54,040 --> 00:05:56,590 dot user input state dot end. 84 00:05:56,590 --> 00:05:57,460 For example. 85 00:05:57,460 --> 00:06:01,630 There's some other different user input states in here, but the only ones that you're going to really 86 00:06:01,630 --> 00:06:04,390 want to care about is begin and end. 87 00:06:05,020 --> 00:06:09,730 So if the input has ended, then we can print input ended. 88 00:06:09,730 --> 00:06:12,880 And again we'll just pass the action name here. 89 00:06:13,270 --> 00:06:17,170 We can also get other information stored inside of the input object. 90 00:06:17,170 --> 00:06:22,540 As you remember, inside of our input object, it stores things such as the key code that was pressed. 91 00:06:22,540 --> 00:06:28,270 It stores the input type, the state we can get, the delta or the position, stuff like that. 92 00:06:28,270 --> 00:06:30,820 But I'm not going to worry about that for now. 93 00:06:31,180 --> 00:06:35,320 But instead what we're going to do is we're going to playtest the game. 94 00:06:35,320 --> 00:06:41,530 And since we have two different actions here, both listening to the exact same inputs, what we should 95 00:06:41,530 --> 00:06:48,850 expect is that this print statement should print twice because we're listening to two different actions. 96 00:06:48,850 --> 00:06:55,360 We have two actions binded, so this should print twice when the input begins and then this should print 97 00:06:55,360 --> 00:06:57,610 twice when the input ends. 98 00:06:58,260 --> 00:07:04,590 Okay, so now that we are in our game, if I listen to some inputs such as my mouse, if I click, as 99 00:07:04,590 --> 00:07:08,070 you can see, we get our input began and then we get our input ended. 100 00:07:08,070 --> 00:07:13,650 Or if I hold down the letter P on my keyboard, input began and then input ended. 101 00:07:13,650 --> 00:07:20,160 So as you can see, the event is working or the action we binded to the context action service is working. 102 00:07:20,160 --> 00:07:25,860 But something you'll notice is that only our example, action two, is being printed in the console, 103 00:07:25,860 --> 00:07:29,100 and our example action one is being ignored. 104 00:07:29,190 --> 00:07:33,840 And this is because we forgot to return a value from our function. 105 00:07:34,200 --> 00:07:40,650 So by default, how the context action service works is that if you have an action or multiple actions 106 00:07:40,650 --> 00:07:47,850 binded to the same input, only one of those actions is going to act upon that input unless you specify 107 00:07:47,850 --> 00:07:48,690 otherwise. 108 00:07:48,690 --> 00:07:55,800 And in order to allow multiple different actions to operate on the exact same input at the end of your 109 00:07:55,800 --> 00:07:58,110 function, you have to return an enum. 110 00:07:59,420 --> 00:08:05,090 And this enum is the context action result dot pass. 111 00:08:05,600 --> 00:08:11,240 So by default if you don't return any value, the value of sync is going to be returned. 112 00:08:11,240 --> 00:08:17,810 And this says the input event will stop at that function and no other bound actions under it will be 113 00:08:17,810 --> 00:08:18,650 executed. 114 00:08:18,860 --> 00:08:24,800 However, if we have again multiple different functions binded to the same input, but we would like 115 00:08:24,800 --> 00:08:29,840 all of them to execute, then we need to pass this pass enum. 116 00:08:30,440 --> 00:08:36,980 And as you can see it says if I pull it up, it says the input event is considered to not have been 117 00:08:36,980 --> 00:08:43,280 handled by function to bind and will continue being passed to actions bound to the same input type. 118 00:08:43,970 --> 00:08:50,960 So if we would like both of these actions to print into the console, then we need to pass this enum 119 00:08:50,960 --> 00:08:51,470 here. 120 00:08:52,510 --> 00:08:58,690 And as you can see, if I start clicking both example action one and example action two is being printed 121 00:08:58,690 --> 00:08:59,560 in the console. 122 00:08:59,560 --> 00:09:02,770 Same thing if I do it with the p button on my keyboard. 123 00:09:03,640 --> 00:09:11,230 Very cool, and for us to see the buttons created on a mobile device will have to emulate this on a 124 00:09:11,230 --> 00:09:12,040 mobile device. 125 00:09:12,040 --> 00:09:18,970 So remember we passed true here to create a button on the screen so we can go ahead and emulate this 126 00:09:19,000 --> 00:09:20,440 on a mobile device. 127 00:09:20,440 --> 00:09:21,610 And then we can play. 128 00:09:22,260 --> 00:09:24,480 And as you can see right here we get two buttons. 129 00:09:24,480 --> 00:09:28,800 One of these belongs to our action one and the other one belongs to action two. 130 00:09:28,830 --> 00:09:33,900 So if I press down this button, as you can see, this button belongs to example action two. 131 00:09:33,900 --> 00:09:35,760 And if I release it, there we go. 132 00:09:35,760 --> 00:09:36,750 Input ended. 133 00:09:36,900 --> 00:09:38,100 Same thing for this one. 134 00:09:38,100 --> 00:09:40,140 This one belongs to example action one. 135 00:09:40,140 --> 00:09:42,270 And if I release it input ended. 136 00:09:42,270 --> 00:09:42,870 So very cool. 137 00:09:42,870 --> 00:09:47,820 We have our two buttons associated with those two different actions. 138 00:09:48,150 --> 00:09:53,820 Now we can go ahead and manipulate or customize these buttons, such as changing the position. 139 00:09:53,820 --> 00:09:57,900 If we don't like where they are on the screen, we can go ahead and move them around. 140 00:09:57,900 --> 00:10:03,360 We can go ahead and set text inside of them, change their size, or even add images inside of these 141 00:10:03,360 --> 00:10:04,080 buttons. 142 00:10:04,880 --> 00:10:10,730 So to do that, what we need to do is refer to the context action service. 143 00:10:10,730 --> 00:10:16,760 And there's a function in there to, for example, set the image of a button and all you need to do 144 00:10:16,760 --> 00:10:22,820 is pass the action name where this button is associated with. 145 00:10:22,820 --> 00:10:25,880 And then you would pass the image ID for that button. 146 00:10:26,510 --> 00:10:30,740 If you would like to set the title, then you would call the set title function again. 147 00:10:30,740 --> 00:10:36,200 You would pass the action name, and then the string that would be placed inside of our button. 148 00:10:36,290 --> 00:10:43,430 So if I set the title for, let's say example action one, and I want to set the text inside of the 149 00:10:43,430 --> 00:10:47,930 button to be something like, uh, let's just do example action one. 150 00:10:48,710 --> 00:10:54,320 Now when the button is going to appear on my screen, it's going to have this text inside of it. 151 00:10:54,470 --> 00:11:00,230 If you would like to manipulate the button and whatever way you'd like, and you want to actually get 152 00:11:00,230 --> 00:11:05,450 the button that is displayed on the screen, then the context action service also has a function called 153 00:11:05,450 --> 00:11:13,880 get button, and this allows you to grab that UI element and change any of the properties inside of 154 00:11:13,880 --> 00:11:17,750 that UI element, such as the size, the position, and things like that. 155 00:11:17,750 --> 00:11:24,200 But the Context Action service automatically includes the ability to set the title, set the image, 156 00:11:24,200 --> 00:11:29,330 or even set the position of the button all within the context action service. 157 00:11:29,720 --> 00:11:35,660 So I'm just going to copy this here and we're going to set it for both example action one and example 158 00:11:35,660 --> 00:11:36,740 action two. 159 00:11:37,240 --> 00:11:39,370 And if we go and playtest our game. 160 00:11:41,090 --> 00:11:46,190 As you can see now, our buttons have the text inside of it. 161 00:11:46,220 --> 00:11:50,570 Unfortunately, as you can see, the text is being cut off because our buttons are so small. 162 00:11:50,960 --> 00:11:57,650 But that is not a problem because we can go ahead, go in here and we can, let's say get one of these 163 00:11:57,650 --> 00:11:58,340 buttons. 164 00:11:58,340 --> 00:11:59,810 I'll store it in a variable. 165 00:11:59,810 --> 00:12:05,660 So we'll do context action service get button, and we'll get the button that's associated with example 166 00:12:05,660 --> 00:12:06,680 action one. 167 00:12:06,980 --> 00:12:12,410 And before we manipulate this button actually what I'm going to do is I'm going to show you this button 168 00:12:12,410 --> 00:12:14,420 inside of our G. 169 00:12:14,450 --> 00:12:16,400 So here's our two buttons. 170 00:12:16,400 --> 00:12:22,940 If we go to my player and we go to player Guy, you can see our context action guy right here. 171 00:12:22,940 --> 00:12:25,310 And then the frame that's storing the buttons. 172 00:12:25,730 --> 00:12:31,190 As you can see right here we have our context action button and another context action button. 173 00:12:31,190 --> 00:12:35,240 And inside of them they have the action icon and the action title. 174 00:12:35,240 --> 00:12:37,400 So the buttons themselves are image buttons. 175 00:12:37,400 --> 00:12:40,580 And inside of them they have the actual icon. 176 00:12:40,580 --> 00:12:43,880 And then they have the text label for the icon itself. 177 00:12:43,880 --> 00:12:49,220 So when we use the get button function, it's going to return to us these image buttons. 178 00:12:49,220 --> 00:12:53,570 And because we get these image buttons, that means we can manipulate all different kinds of properties 179 00:12:53,570 --> 00:12:59,360 such as the position, the size we can change background color, all sorts of stuff, whatever we would 180 00:12:59,360 --> 00:13:01,940 like with these different buttons. 181 00:13:02,660 --> 00:13:08,360 So for example, if I would like to make the button bigger, then I can refer to my button here and 182 00:13:08,360 --> 00:13:10,820 I'm going to denote it as an image button. 183 00:13:11,390 --> 00:13:14,750 I can go ahead and set the button dot size equal to. 184 00:13:14,750 --> 00:13:19,400 Let's say uh we're going to create a new Utum two from offset. 185 00:13:20,270 --> 00:13:23,690 Let's say we want to make the button 200 by 200 pixels. 186 00:13:24,470 --> 00:13:31,820 So now our example action one button is going to be much larger than our example action two button. 187 00:13:31,820 --> 00:13:35,480 So if we go ahead and play test our game. 188 00:13:37,970 --> 00:13:42,050 As you can see, our example action one button is now ginormous. 189 00:13:42,050 --> 00:13:46,340 And as you can see, I can click it right here and we get input began and input ended. 190 00:13:46,340 --> 00:13:48,380 For example action one. 191 00:13:48,380 --> 00:13:49,310 Very cool. 192 00:13:50,110 --> 00:13:55,510 So this is how we can use the Context Action service to listen to user input in different situations. 193 00:13:55,510 --> 00:14:02,110 Once we're done with a particular context and we no longer need to listen to these particular inputs 194 00:14:02,110 --> 00:14:09,820 anymore, then we can easily unbind these functions by using the context action service unbind action 195 00:14:09,820 --> 00:14:10,420 function. 196 00:14:10,420 --> 00:14:12,970 And all we need to do is pass the action name. 197 00:14:12,970 --> 00:14:19,150 And once that's done now, we will no longer be listening to whatever input is associated with that 198 00:14:19,150 --> 00:14:20,500 particular action. 199 00:14:21,040 --> 00:14:26,680 The Context Action service allows us to add cross-platform support to our games quickly and efficiently, 200 00:14:26,680 --> 00:14:32,230 and again, it is recommended to be used in most situations over the user input service. 201 00:14:32,230 --> 00:14:36,250 I hope you're learning a lot and I will see you in the next lecture.